package com.moon.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.moon.dao.TAuctionMapper;
import com.moon.dao.TProductMapper;
import com.moon.dto.EsProduct;
import com.moon.dto.ProductVo;
import com.moon.dto.TUser;
import com.moon.entity.TAuction;
import com.moon.entity.TProduct;
import com.moon.es.EsDataWriter;
import com.moon.es.EsProductRepository;
import com.moon.utils.IdWorker;
import com.moon.utils.ProductUtils;
import com.moon.utils.RedisLock;
import org.elasticsearch.index.query.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;
import tk.mybatis.mapper.entity.Example;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class ProductService{

    @Autowired
    TAuctionMapper auctionMapper;

    @Autowired
    TProductMapper productMapper;

    @Autowired
    EsProductRepository esProductRepository;

    @Autowired
    @Qualifier("idWorker1")
    IdWorker idWorker1;

    @Autowired
    @Qualifier("esProduct")
    EsDataWriter esDataWriter;

    private RedisLock redisLock = new RedisLock(new Jedis("localhost", 6379));

    public PageInfo selectByEs(Long sellerId, String keyword, Integer status, Integer currentPage, Integer pageSize) {

        //判断es是否有数据,如果没有数据就写入
        if (!esProductRepository.findAll().iterator().hasNext())
            esDataWriter.dataWrite();
        //es查询
        //构建查询条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        //query
        MatchQueryBuilder query1 = QueryBuilders.matchQuery("productName", keyword);
        TermQueryBuilder query2 = QueryBuilders.termQuery("sellerId", sellerId);
        TermQueryBuilder query3 = null;
        if (status != null && status != -1) {
            query3 = QueryBuilders.termQuery("status", status);
        }
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(query1);
        boolQueryBuilder.must(query2);
        if (query3 != null)
            boolQueryBuilder.must(query3);

        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        //分页条件
        //注意: es中的分页是从第0页开始的

        nativeSearchQueryBuilder.withPageable(PageRequest.of(currentPage - 1, pageSize));

        //排序
//        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("buyCount").order(SortOrder.DESC));

        org.springframework.data.domain.Page<EsProduct> esProductPage = esProductRepository.search(nativeSearchQueryBuilder.build());

        //将 Es的page 转换 pagehelper的 page
        PageHelper.startPage(currentPage, pageSize);
        PageInfo<EsProduct> pageInfo = new PageInfo<>();
        pageInfo.setPages(esProductPage.getTotalPages());
        pageInfo.setTotal(esProductPage.getTotalElements());
        pageInfo.setList(esProductPage.getContent());

        return pageInfo;
    }

    public PageInfo selectAll(Long userId, Integer status, Integer currentPage, Integer pageSize) {
        TProduct tProduct = new TProduct();
        tProduct.setSellerId(userId);
        List<TProduct> list;
        PageHelper.startPage(currentPage, pageSize);
        if (status == null || status == -1) {
            //状态为查全部
            list = productMapper.selectBySellerId(userId);
        } else {
            //根据状态查询
            tProduct.setStatus(status);
            list = productMapper.select(tProduct);
        }

        PageInfo productInfo = new PageInfo<>(list);
        List<ProductVo> proList = new ArrayList<>();
        for (TProduct product : list) {
            TAuction auction = new TAuction();
            auction.setProductId(product.getId());
            //竞拍室集合
            List<TAuction> auctionList = auctionMapper.select(auction);
            ProductVo vo = ProductUtils.getList(product);
            vo.setAuctionList(auctionList);
            //进行中的竞拍
            if (auctionList!=null){
                for (TAuction tAuction : auctionList) {
                    if (tAuction.getStatus() == 1) {
                        vo.setAuction(tAuction);
                    }
                }
            }
            proList.add(vo);
        }
        productInfo.setList(proList);
        return productInfo;
    }

    @Transactional
    public String update(long id, String productName, List<MultipartFile> fileList, String productDetail) {
        redisLock.executeWithLock(()->{
            List<String> nList = new ArrayList<>();

            if (fileList != null) {
                for (MultipartFile file : fileList) {
                    String originalFilename = file.getOriginalFilename();
                    if (!"".equals(originalFilename)) {
                        String fileName = "http://localhost:10002/imgs/product/" + originalFilename;

//                控制如果不是图片就不让上传
//                String contentType = source.getContentType();
//            if (!"jpg".equals(contentType) || !"png".equals(contentType)) {
//                return "forward:/car/selectCarByT";
//            }

//                    获取到img这个目录的真实路径
                        String realPath = "F:\\image\\product"; // img/fileName
//                String read_img_path = realPath + "\\" + fileName;
                        String read_img_path = realPath + "\\" + originalFilename;

//                     使用multipart对象的方法保存文件
//                    上传的文件流保存在上面组合的指定路径下
                        try {
                            file.transferTo(new File(read_img_path));
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }

                        //保存图片的路径到数据
                        //图片路径放到集合里
                        nList.add(fileName);
                    }
                }
            }

            if (nList.size() > 0) {
                ProductVo productVo = new ProductVo();
                productVo.setId(id);
                productVo.setProductImgList(nList);
                if (productName != null && !"".equals(productName)) {
                    productVo.setProductName(productName);
                }
                if (productDetail != null && !"".equals(productDetail)) {
                    productVo.setProductDetail(productDetail);
                }

                TProduct pro = ProductUtils.getString(productVo);
                Example example = new Example(TProduct.class);
                example.createCriteria().andEqualTo("id", id);
                productMapper.updateByExampleSelective(pro, example);
            } else {
                TProduct product = new TProduct();
                if (productName != null && !"".equals(productName)) {
                    product.setProductName(productName);
                }
                if (productDetail != null && !"".equals(productDetail)) {
                    product.setProductDetail(productDetail);
                }

                Example example = new Example(TProduct.class);
                example.createCriteria().andEqualTo("id", id);
                productMapper.updateByExampleSelective(product, example);
            }
            //更新ES数据
            esProductRepository.deleteAll();
            esDataWriter.dataWrite();
        });
        return "success";
    }

    @Transactional
    public String insert(String productName, List<MultipartFile> fileList, String productDetail, TUser user) {
        redisLock.executeWithLock(()->{
            List<String> nList = new ArrayList<>();

            for (MultipartFile file : fileList) {
                String originalFilename = file.getOriginalFilename();
                if (!"".equals(originalFilename)) {
                    String fileName = "http://localhost:10002/imgs/product/" + originalFilename;

//                控制如果不是图片就不让上传
//                String contentType = source.getContentType();
//            if (!"jpg".equals(contentType) || !"png".equals(contentType)) {
//                return "forward:/car/selectCarByT";
//            }

//                    获取到img这个目录的真实路径
                    String realPath = "F:\\image\\product"; // img/fileName
//                String read_img_path = realPath + "\\" + fileName;
                    String read_img_path = realPath + "\\" + originalFilename;

//                     使用multipart对象的方法保存文件
//                    上传的文件流保存在上面组合的指定路径下
                    try {
                        file.transferTo(new File(read_img_path));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }

                    //保存图片的路径到数据
                    //图片路径放到集合里
                    nList.add(fileName);
                }
            }
            ProductVo productVo = new ProductVo();
            productVo.setId(idWorker1.nextId());
            productVo.setSellerId(user.getId());
            productVo.setProductName(productName);
            productVo.setProductImgList(nList);
            productVo.setProductDetail(productDetail);
            productVo.setStatus(0);
            productMapper.insert(ProductUtils.getString(productVo));
            //更新ES数据
            esProductRepository.deleteAll();
            esDataWriter.dataWrite();
        });
        return "success";
    }

    @Transactional
    public String delete(long productId) {
        redisLock.executeWithLock(()->{
            TProduct product = new TProduct();
            product.setStatus(1);
            Example example = new Example(TProduct.class);
            example.createCriteria().andEqualTo("id", productId);
            productMapper.updateByExampleSelective(product, example);
            //更新ES数据
            esProductRepository.deleteAll();
            esDataWriter.dataWrite();
        });
        return "success";
    }


    public Long selectSellerIdByProductId(Long productId) {
        TProduct product = new TProduct();
        product.setId(productId);
        TProduct product1 = productMapper.selectOne(product);
        return product1.getSellerId();
    }
}
